# -*- coding: utf-8 -*-
from appium import webdriver
import re
import time
import random

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By


platformName = 'Android' #手机系统

# platformVersion = '5.1.1' #安卓版本号
# platformVersion = '8.1.0' #安卓版本号
platformVersion = '9' #安卓版本号

# deviceName = 'IR6SIVGYTWUO9LQC'#安卓号
deviceName = 'SSV4W8JZFU4SLJ6S'#oppo安卓号
# deviceName = '7907feb6'#vivo安卓号

appPackage = 'com.taobao.mobile.dipei'
appActivity = 'com.eg.android.AlipayGphone.AlipayLogin'
# automationName = 'Uiautomator2'
unicodeKeyboard = True
noReset = True


class Dipei():
    """
    口碑类
    """
    def __init__(self):
        self.desired_caps = {}
        self.desired_caps['platformName'] = platformName
        self.desired_caps['platformVersion'] = platformVersion
        self.desired_caps['deviceName'] = deviceName
        self.desired_caps['appPackage'] = appPackage
        self.desired_caps['appActivity'] = appActivity
        # self.desired_caps['automationName'] = automationName
        # self.desired_caps['unicodeKeyboard'] = unicodeKeyboard
        self.desired_caps['noReset'] = noReset

        self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=self.desired_caps)

        self.wait = WebDriverWait(self.driver, 300)
        self.wait_phone = WebDriverWait(self.driver, 11)
        self.driver.implicitly_wait(11)

    def select_city(self, city):
        """
        选择城市
        :return:
        """
        # 点击首个页面选择city的按钮
        self.wait.until(EC.element_to_be_clickable((By.ID, 'com.alipay.android.phone.discovery.o2ohome:id/city'))).click()
        # 点选指定的city
        time.sleep(2)
        self.driver.find_element_by_android_uiautomator('new UiSelector().text("{}")'.format(city)).click()
        time.sleep(1)

    def input_category(self, first_category, second_category):
        """
        进入到指定类目的活动页面
        :return:
        """
        # 点击全部
        time.sleep(1)
        self.wait.until(EC.element_to_be_clickable((By.ID, '全部'))).click()
        # self.driver.find_element_by_xpath('//android.view.ViewGroup[@content-desc="全部"]').click()

        # 点选一级类目
        time.sleep(2)
        self.driver.find_element_by_android_uiautomator('new UiSelector().text("{}")'.format(first_category)).click()

        # 点选二级类目
        self.wait.until(EC.element_to_be_clickable((By.ID, second_category))).click()

    def get_title(self):
        """
        进入打车页面获取title，并返回
        :return:
        """
        # 点击打车按钮
        title = None

        current_activity = self.driver.current_activity

        # 新活动页面，要到打车界面才能获得title的界面，判断活动界面
        if current_activity == 'com.alipay.tiny.app.Page.PageActivity':
            # 点击打车按钮
            self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'android.support.v7.widget.RecyclerView')))
            time.sleep(2)
            self.driver.find_element_by_class_name(
                'android.support.v7.widget.RecyclerView').find_elements_by_class_name('android.widget.FrameLayout')[
                3].find_element_by_class_name('android.view.ViewGroup').find_element_by_class_name(
                'android.view.ViewGroup').find_elements_by_class_name('android.view.ViewGroup')[
                0].find_elements_by_class_name('android.view.ViewGroup')[1].click()

            # 获取进入打车页面的activity，准备接下来判断
            x_activity = self.driver.current_activity

            # 高德打车页面
            if x_activity == 'com.alipay.mobile.nebulacore.ui.H5Activity':

                while True:
                    try:
                        # 获取打车界面活动title
                        self.wait.until(EC.visibility_of_element_located((By.ID, 'to')))
                        title = self.driver.find_element_by_id('to').get_attribute('text').strip()
                        print(title)
                        break
                    except Exception as e:
                        print(e)
                        time.sleep(1)
                        self.driver.press_keycode(4)
                        time.sleep(1)
                        self.driver.find_element_by_accessibility_id('离开').click()
                        time.sleep(2)

                        # 再次点击进入打车界面
                        self.driver.find_element_by_class_name(
                            'android.support.v7.widget.RecyclerView').find_elements_by_class_name(
                            'android.widget.FrameLayout')[
                            3].find_element_by_class_name('android.view.ViewGroup').find_element_by_class_name(
                            'android.view.ViewGroup').find_elements_by_class_name('android.view.ViewGroup')[
                            0].find_elements_by_class_name('android.view.ViewGroup')[1].click()

                # 通过后点击返回到主活动页面
                time.sleep(2)
                self.driver.press_keycode(4)
                time.sleep(2)
                self.driver.find_element_by_accessibility_id('离开').click()

            # 滴滴打车页面，有取不到值的问题
            else:
                # title = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//android.webkit.WebView[@content-desc="滴滴出行"]/android.view.View[1]/android.view.View[2]/android.view.View[3]'))).get_attribute('content-desc')
                while True:
                    try:
                        # 进入滴滴打车界面
                        print('bbb')
                        self.wait.until(
                            EC.element_to_be_clickable((By.ID, 'spa-webapp')))
                        time.sleep(6)

                        # title1 = self.driver.find_element_by_id('spa-webapp').find_elements_by_class_name('android.view.View')[
                        #     1].find_elements_by_class_name('android.view.View')[3].get_attribute('content-desc')
                        # print(title1)

                        # title = self.driver.find_element_by_accessibility_id('滴滴出行').find_element_by_id('spa-webapp').find_elements_by_class_name('android.view.View')[1].find_elements_by_class_name('android.view.View')[2].get_attribute('content-desc')
                        # print(title)
                        title = self.driver.find_element_by_xpath('//android.webkit.WebView[@content-desc="滴滴出行"]/android.view.View[1]/android.view.View[2]/android.view.View[3]').get_attribute('content-desc')
                        title = re.search(r'目的地(.*)', title).group(1)
                        print('aaaa')
                        break
                    except Exception as e1:
                        print(e1)
                        # 退出到口碑活动界面
                        time.sleep(2)
                        self.driver.press_keycode(keycode=4)

                        # 等待判断是否有父元素
                        self.wait.until(
                            EC.element_to_be_clickable((By.CLASS_NAME, 'android.support.v7.widget.RecyclerView')))
                        time.sleep(1)
                        # 再次点击打车
                        self.driver.find_element_by_class_name(
                            'android.support.v7.widget.RecyclerView').find_elements_by_class_name(
                            'android.widget.FrameLayout')[
                            3].find_element_by_class_name('android.view.ViewGroup').find_element_by_class_name(
                            'android.view.ViewGroup').find_elements_by_class_name('android.view.ViewGroup')[
                            0].find_elements_by_class_name('android.view.ViewGroup')[1].click()
                        time.sleep(4)

                print(title)
                self.driver.press_keycode(keycode=4)

        # 老活动页面，直接活动页面获取到名称的
        elif current_activity == 'com.alipay.android.phone.discovery.o2o.detail.activity.MerchantDetailsActivity':

            # 点击分享，刷新页面
            time.sleep(2)
            self.click_phone(0.81, 0.072)
            # self.driver.find_elements_by_id('com.alipay.android.phone.discovery.o2o.build:id/btn_container')[1].click()
            # self.wait.until(EC.element_to_be_clickable((By.ID, 'com.alipay.android.phone.discovery.o2o.build:id/btn_container'))).click()
            # self.driver.find_element_by_android_uiautomator('new UiSelector().content-desc("分享该店铺")').click()
            # self.wait.until(EC.element_to_be_clickable((By.XPATH, '//android.widget.RelativeLayout[@content-desc="分享该店铺"]/android.widget.LinearLayout'))).click()

            # 点击返回
            time.sleep(2)
            self.driver.press_keycode(keycode=4)

            # 等待包含title的控件出现
            self.wait.until(EC.visibility_of_element_located((By.ID, 'com.alipay.android.phone.discovery.o2o.build:id/nativeContainer')))
            # 取出活动的title
            title = self.driver.find_element_by_id('com.alipay.android.phone.discovery.o2o.build:id/nativeContainer').find_elements_by_class_name('android.widget.FrameLayout')[0].find_element_by_class_name('android.widget.LinearLayout').find_element_by_class_name('android.widget.TextView').get_attribute('text').strip()
            print(title)

        # 未知页面
        else:
            title = title
        return title

    def get_phone(self):
        """
        进入拨打电话页面获取手机号，并返回
        :param driver:
        :return:
        """
        phone1 = None
        # 获取current_activity
        time.sleep(1)
        current_activity = self.driver.current_activity
        time.sleep(1)

        # 老活动页面
        if current_activity == 'com.alipay.android.phone.discovery.o2o.detail.activity.MerchantDetailsActivity':

            # 点击电话按钮
            try:
                self.wait_phone.until(EC.element_to_be_clickable((By.ID, '电话按钮'))).click()
            except Exception as e:
                print(e)
                return False
            # self.wait.until(EC.element_to_be_clickable((By.ID, '电话按钮'))).click()

            # 直接进入拨打电话页面
            if self.driver.current_activity == '.DialtactsActivityAlias':
                self.driver.wait_activity('.TwelveKeyDialer', 10)

                phone1 = self.wait.until(EC.element_to_be_clickable((By.ID, 'com.android.contacts:id/normal_input'))).get_attribute('text').strip().replace(' ', '')
                print(phone1)
                time.sleep(1)
                self.driver.press_keycode(keycode=4)
                time.sleep(2)

            # 屏幕中间出现电话号码
            else:
                # 取屏幕中间的电话号码
                time.sleep(2)

                # 等到插件出现
                self.wait.until(EC.visibility_of_element_located((By.ID, 'com.alipay.mobile.antui:id/dialog_listView')))
                # 取出所有手机号
                tels_obj = self.driver.find_element_by_id('com.alipay.mobile.antui:id/dialog_listView').find_elements_by_id('com.alipay.mobile.antui:id/item_name')
                for tel_obj in tels_obj:
                    tel = tel_obj.get_attribute('text').strip()
                    print(tel)
                    try:
                        # phone1 = re.search(r'1\d{10}', tel).group(0)
                        phone1 = re.search(r'\d+-?\d+', tel).group(0)

                        with open('koub.txt','r',encoding='utf-8') as f:
                            if phone1 in f.read():
                                print("号码已经存在!跳过")
                                time.sleep(2)
                                continue
                    except Exception as e:
                        print('取不到')
                        continue
                    else:
                        break

                # 返回
                time.sleep(2)
                self.driver.press_keycode(keycode=4)
                time.sleep(2)

        # 新活动页面，这里没有用elif是因为出现过找不到新活动页面activity的现象
        else:
            time.sleep(3)
            # self.driver.find_element_by_xpath(
            #     '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.widget.FrameLayout/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[4]/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup[1]/android.view.ViewGroup[3]'
            # ).click()

            # 存在控件变化的现象
            try:
                # self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'android.support.v7.widget.RecyclerView')))
                # recycler_wait = WebDriverWait(recycler, 300)
                time.sleep(1)
                # 点击电话按钮 这里需要增加一个判断判断是否有 电话按钮
                try:
                    self.driver.find_element_by_class_name('android.support.v7.widget.RecyclerView').find_elements_by_class_name('android.widget.FrameLayout')[3].find_element_by_class_name('android.view.ViewGroup').find_element_by_class_name('android.view.ViewGroup').find_elements_by_class_name('android.view.ViewGroup')[0].find_elements_by_class_name('android.view.ViewGroup')[2].click()
                except Exception as e:
                    print(e)
                    return False
                time.sleep(2)
                # self.wait.until(EC.element_to_be_clickable((By.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.widget.FrameLayout/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[4]/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup[1]/android.view.ViewGroup[3]'))).click()
                # self.driver.find_element_by_xpath(
                #     '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.widget.FrameLayout/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[4]/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup[1]/android.view.ViewGroup[3]'
                # ).click()
                # self.driver.find_element_by_android_uiautomator('new UiSelector().className("android.view.ViewGroup")[]')
                # self.click_phone(per_x=0.95, per_y=0.35)
                # 第二种想不出来如何判断
                # self.driver.find_element_by_xpath(
                #     '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup/android.widget.FrameLayout/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[3]/android.view.ViewGroup/android.view.ViewGroup/android.view.ViewGroup[1]/android.view.ViewGroup[3]'
                #     ).click()
            except Exception as e:
                print(e)

            else:
                # 直接进入拨打电话界面
                # print(self.driver.current_activity)
                if self.driver.current_activity == '.DialtactsActivityAlias':
                    phone1 = self.driver.find_element_by_id('com.android.contacts:id/normal_input').get_attribute('text').strip().replace(' ', '')
                    print(phone1)
                    time.sleep(1)
                    self.driver.press_keycode(keycode=4)
                    time.sleep(1)

                # 页面底部出现电话号码
                else:
                    try:
                        # 点击底部指定位置的电话号码
                        self.click_phone(per_x=0.5, per_y=0.82)
                        time.sleep(2)
                    except Exception as e:
                        print('点击页面底部电话号码失败')
                    else:
                        try:
                            # 进入到拨打电话界面

                            phone1 = self.driver.find_element_by_id('com.android.contacts:id/normal_input').get_attribute('text').strip().replace(' ', '')
                            print(phone1)
                        except Exception as e:
                            print("进入打电话页面失败！")

                    # 返回到活动主页面
                    time.sleep(1)
                    self.driver.press_keycode(keycode=4)
                    time.sleep(2)

        # 总体判断是否是电话
        phone = None
        if phone1:
            try:
                phone = re.search(r'\d+-?\d+', phone1).group(0)
                with open(r'koub.txt', 'r',encoding='utf-8') as f:
                    if phone1 in f.read():
                        print('号码已经存在!')
                        time.sleep(2)
                        return False
            except Exception as e:
                print(e)
        else:
            phone = None

        return phone

    def swipeDown(self, t):
        """
        屏幕向下滑动
        :param t:
        :return:
        """
        x = self.driver.get_window_size()['width']
        y = self.driver.get_window_size()['height']
        x1 = int(x * 0.8)  # x坐标
        y1 = int(y * 0.95)  # 起始y坐标
        y2 = int(y * 0.7)  # 终点y坐标
        self.driver.swipe(x1, y1, x1, y2, t)
        return self.driver

    def click_phone(self, per_x, per_y):
        """
        点击手机屏幕指定相对位置
        :return:
        """
        x = self.driver.get_window_size()['width']
        y = self.driver.get_window_size()['height']
        self.driver.tap([(x * per_x, y * per_y)])

    def main(self):
        """
        口碑类开启
        :return:
        """
        time.sleep(2)

        # 一级类目
        def start():
            fist_categorys = ['亲子', '教育技能培训','运动健身']
            list_1 = ['少儿才艺','早教中心','少儿运动','亲子游泳','科普场馆','少儿外语','亲子游乐']
            list_2 = ['美术培训','外语培训','辅导升学','音乐培训','舞蹈培训']
            list_3 = ['舞蹈','溜冰场','跆拳道馆','武术格斗']
            print(">>>选择一级目录---------------------")
            print(f" 1-{fist_categorys[0]}\n 2-{fist_categorys[1]}\n 3-{fist_categorys[2]}\n")
            num = input('选择一级目录:    ')
            while num not in ["1",'2','3']:
                num = input('错误!从新选择:')
            if num =='1':
                first_category = fist_categorys[int(num)-1]
                print(f'当前已选择:{first_category}')
                for index,val in enumerate(list_1):
                    print(f'{index}-{val}')
                number = input("选择二级目录:")
                second_category = list_1[int(number)]
                print(f'二级目录选择:{second_category}')
            elif num=='2':
                first_category = fist_categorys[int(num)-1]
                print(f'当前已选择:{first_category}')
                for index, val in enumerate(list_2):
                    print(f'{index}-{val}')
                number = input("选择二级目录:")
                second_category = list_2[int(number)]
                print(f'二级目录选择:{second_category}')

            elif num=='3':
                first_category = fist_categorys[int(num)-1]
                print(f'当前已选择:{first_category}')
                for index, val in enumerate(list_3):
                    print(f'{index}-{val}')
                number = input("选择二级目录:")
                second_category = list_3[int(number)]
                print(f'二级目录选择:{second_category}')

            else:
                print('出现错误!')
                return 0

            print('请输入要翻页的次数:')
            try:

                page_number=  input('>>>>>>>>>')
            except:
                page_number = 1

            start_y = input('是否开始爬取,否则返回(enter/f):')
            while start_y !='' and start_y!='f':
                start_y = input('是否开始爬取,否则返回(enter/f):')
            if start_y=='':
                print('第一类:',first_category)
                print('第二类:',second_category)
                print(' 翻页:',page_number)
                return first_category,second_category,page_number
            else:
                start()

        # 调用开始函数
        first_category, second_category,page_number =  start()

        with open('cate_log.txt', 'w', encoding='utf-8') as fz:
            fz.write(f'当前抓取的科目是:{first_category}-{second_category}')
        print('---'*44)
        # 亲子:  少儿才艺,早教中心,少儿运动,亲子游泳,科普场馆,儿童外语,亲子游乐
        # 教育技能培训: 美术培训,外语培训,辅导升学,音乐培训,舞蹈培训,
        # 运动健身: 舞蹈,溜冰场,跆拳道馆,武术场馆
        # 目前 杭州 北京 上海 深圳 广州 郑州  苏州 重庆 武汉 西安 成都 天津 南京 长沙 沈阳 青岛 宁波 东莞 无锡 昆明 大连 厦门 合肥 佛山 福州 哈尔滨 济南 温州 已经抓取
        self.select_city("郑州")
        """
            一线城市: 上海,北京,深圳,广州
            新一线城市: 苏州,杭州,郑州,重庆,武汉,成都,西安,天津,南京,长沙,沈阳,青岛,宁波,东莞,无锡
            二线城市:昆明,大连,厦门,合肥,佛山,福州,哈尔滨,济南,温州,长春,石家庄,常州,泉州,南宁,贵阳,南昌,南通,金华,徐州,太原,嘉兴,烟台,惠州,保定,台州,中山,绍兴,乌鲁木齐,潍坊,兰州
            三线城市:珠海,镇江,海口,扬州
        """
        self.input_category(first_category=first_category, second_category=second_category)

        # # 根据滑动指定的次数，滑动到指定页面
        try:

            page_num = int(page_number)
        except Exception as e:
            print("输入错误!")
            page_num = 1
        for i in range(page_num):
            try:
                time.sleep(1)
                self.swipeDown(500)
            except Exception as e:
                time.sleep(1)
                continue

        # 存取的索引
        # i = 1
        j = 3
        while True:
            if j == 5:
                j = 3
            print(j)
            time.sleep(random.choice([2, 3, 4]))
            # 点击一个插件列表
            # self.driver.find_element_by_id('com.alipay.android.phone.discovery.o2o.build:id/search_recycler_view').find_elements_by_class_name('android.view.ViewGroup')[j].click()
            # 点击 列表中的活动 进入页面,
            # self.wait.until(EC.element_to_be_clickable((By.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[2]/android.support.v7.widget.RecyclerView/android.view.ViewGroup[{}]'.format(str(j))))).click()
            try:
                # self.driver.find_element_by_xpath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[2]/android.support.v7.widget.RecyclerView/android.view.ViewGroup[{}]'.format(str(j))).click()
                """
                    对于不同的页面使用不同的选择,上边或者下边
                """
                self.wait.until(EC.element_to_be_clickable((By.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[1]/android.support.v7.widget.RecyclerView/android.view.ViewGroup[{}]'.format(str(j))))).click()
            except Exception as e:
                print(e)
                continue

            time.sleep(3)

            # 获取手机号
            phone = self.get_phone()
            # 判断手机号非空，执行获取title
            print(phone)
            if phone:
                # 添加一个判断 判断是否手机号已经存在了
                time.sleep(3)
                try:
                    title = self.get_title()
                except Exception as e:
                    print(f'获取title时出错:{e}')
                    self.driver.press_keycode(keycode=4)
                    continue
                time.sleep(1)
                try:
                    with open("koub.txt", 'a',encoding='utf-8') as file:
                        file.write(phone + '/' + title + '\n')
                    time.sleep(1)
                except Exception as e:
                    print(e)
                print(f'当前爬取科目为:{second_category}')
                print('--'*34)
                # 返回插件列表
                self.driver.press_keycode(keycode=4)
                time.sleep(2)

            else:
                time.sleep(2)
                self.driver.press_keycode(keycode=4)
            time.sleep(2)
            if j < 4:
                j += 1
            elif j == 4:
                j += 1
                for i in range(2):
                    try:
                        self.swipeDown(500)
                        time.sleep(2)
                    except Exception as e:
                        print(e)

# 19106848259
# pip install requests -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
if __name__ == '__main__':
    dipei = Dipei()

    dipei.main()
